package com.submit.demo.service.impl;

import com.csvreader.CsvReader;
import com.submit.demo.common.api.CommonPage;
import com.submit.demo.config.MinIOProperties;
import com.submit.demo.dto.SubmitterInsertParam;
import com.submit.demo.dto.SubmitterReturnData;
import com.submit.demo.model.*;
import com.submit.demo.repository.ColSubRepository;
import com.submit.demo.repository.ColTagRepository;
import com.submit.demo.repository.SubTaskRepository;
import com.submit.demo.repository.SubmitterRepository;
import com.submit.demo.service.ColSubService;
import com.submit.demo.service.SubmitterService;
import com.submit.demo.util.MinIOUtil;
import com.submit.demo.util.MongoUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SubmitterServiceImpl implements SubmitterService {
    @Autowired
    private SubmitterRepository submitterRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private MongoUtil mongoUtil;

    @Autowired
    private ColSubRepository colSubRepository;

    @Autowired
    private ColTagRepository colTagRepository;

    @Autowired
    private SubTaskRepository subTaskRepository;

    @Autowired
    private MinIOProperties minIOProperties;


    public boolean isSubmitterExist(String phone) {
        if(submitterRepository.findSubmitterByPhone(phone) != null) return true;
        return false;
    }

    @Override
    public CommonPage<SubmitterReturnData> getSlist(String tid, Integer currentPage, Integer pageSize) {
        Query query = new Query(Criteria.where("tid").is(tid).and("status").is(1));
        long count = mongoTemplate.count(query, SubTask.class);
        mongoUtil.start(currentPage, pageSize, query);
        List<SubTask> list = mongoTemplate.find(query, SubTask.class);
        List<SubmitterReturnData> data = new ArrayList<>();
        for(SubTask subTask : list){
            SubmitterReturnData d = new SubmitterReturnData();
            d.setSubmitter(submitterRepository.findById(subTask.getSid()).get());
            d.setWords(subTask.getWords());
            data.add(d);
        }
        return mongoUtil.pageHelper(count, data);
    }

    @Override
    public CommonPage<SubmitterReturnData> getDlist(String tid, Integer currentPage, Integer pageSize) {
        Query query = new Query(Criteria.where("tid").is(tid).and("status").is(0));
        long count = mongoTemplate.count(query, SubTask.class);
        mongoUtil.start(currentPage, pageSize, query);
        List<SubTask> list = mongoTemplate.find(query, SubTask.class);
        List<SubmitterReturnData> data = new ArrayList<>();
        for(SubTask subTask : list){
            SubmitterReturnData d = new SubmitterReturnData();
            d.setSubmitter(submitterRepository.findById(subTask.getSid()).get());
            d.setWords(subTask.getWords());
            data.add(d);
        }
        return mongoUtil.pageHelper(count, data);
    }

    @Override
    public Integer crSub(SubmitterInsertParam param) {
        Submitter submitter = new Submitter();
        submitter.setName(param.getName());
        submitter.setPhone(param.getPhone());
        submitter.setWechat(param.getWechat());
        submitter = submitterRepository.insert(submitter);
        ColSub colSub = new ColSub();
        colSub.setCid(param.getCid());
        colSub.setSid(submitter.getId());
        List<String> tags = new ArrayList<>();
        tags.add("所有");
        tags.add(param.getTag());
        colSub.setTags(tags);
        colSubRepository.insert(colSub);
        return 1;
    }

    @Override
    public Integer insertFromCsv(String cid, MultipartFile file) {
        List<Submitter> list = new ArrayList<>();
        try {
            CsvReader csvReader = new CsvReader(file.getInputStream(),',', Charset.forName("GBK"));
            csvReader.readHeaders();
            StringBuilder sb = new StringBuilder();
            while(csvReader.readRecord()){
                Submitter submitter = new Submitter();
                String[] strs = csvReader.getValues();
                submitter.setName(new String(strs[0].getBytes(), "UTF-8"));
                submitter.setPhone(strs[1]);
                submitter.setWechat(strs[2]);
                submitter.setStatus(1);
                if(!isSubmitterExist(submitter.getPhone()) && !list.contains(submitter)) list.add(submitter);
                else sb.append(submitter.getName() + ' ');
            }
            log.info("下列提交人已存在: " + sb.toString());
            List<Submitter> submitters = submitterRepository.insert(list);
            for(Submitter s : submitters){
                ColSub colSub = new ColSub();
                colSub.setCid(cid);
                colSub.setSid(s.getId());
                List<String> tags = new ArrayList<>();
                tags.add("所有");
                colSub.setTags(tags);
                colSubRepository.insert(colSub);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e){
            e.printStackTrace();
        }
        return 1;
    }

    @Override
    public CommonPage<Submitter> getListWithTag(String cid, List<String> tags, Integer currentPage, Integer pageSize) {
        Query query = new Query(Criteria.where("tags").in(tags));
        long count = mongoTemplate.count(query, ColSub.class);
        mongoUtil.start(currentPage, pageSize, query);
        List<ColSub> list = mongoTemplate.find(query, ColSub.class);
        List<String> sids = list.stream().map(ColSub::getSid).collect(Collectors.toList());
        query = new Query(Criteria.where("id").in(sids));
        List<Submitter> submitters = mongoTemplate.find(query, Submitter.class);
        return mongoUtil.pageHelper(count, submitters);
    }

    @Override
    public CommonPage<Submitter> getList(Integer currentPage, Integer pageSize) {
        Query query = new Query();
        long count = mongoTemplate.count(query, Submitter.class);
        mongoUtil.start(currentPage, pageSize, query);
        return mongoUtil.pageHelper(count, mongoTemplate.find(query, Submitter.class));
    }

    @Override
    public Integer del(String sid) {
        colSubRepository.deleteAllBySid(sid);
        submitterRepository.deleteById(sid);
        List<SubTask> list = subTaskRepository.findAllBySid(sid);
        List<Word> words = new ArrayList<>();
        list.stream().map(SubTask::getWords).forEach(
                words1 -> words.addAll(words)
        );
        MinIOUtil.deleteWords(minIOProperties.getBucketName(), words);
        subTaskRepository.deleteAllBySid(sid);
        return 1;
    }
}
